package com.youlu.campus.service.ca.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;

import com.youlu.campus.entity.ActivityCaOrg;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityUserRecord;
import com.youlu.campus.entity.CaBackgroundPic;
import com.youlu.campus.entity.CaCertificateConfig;
import com.youlu.campus.entity.CaCertificateLog;
import com.youlu.campus.entity.CaGroupInfo;
import com.youlu.campus.entity.CaTemplate;
import com.youlu.campus.entity.CaTemplateUniversity;
import com.youlu.campus.entity.CertificateActivityConfig;
import com.youlu.campus.entity.CertificateNoInfo;
import com.youlu.campus.entity.OrderInfo;
import com.youlu.campus.entity.PayButtonConfigPage;
import com.youlu.campus.entity.PayCategoryConfig;
import com.youlu.campus.entity.PayConfigPage;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.UserCaOrg;
import com.youlu.campus.entity.UserCaRecord;
import com.youlu.campus.entity.UserInfoExtend;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.UserPaperCaReceiveHistory;
import com.youlu.campus.entity.UserParticipateActivityInfo;
import com.youlu.campus.entity.VO.req.CaCollectReq;
import com.youlu.campus.entity.VO.req.PlatformActivityQueryVO;
import com.youlu.campus.entity.VO.res.CaCollectRes;
import com.youlu.campus.entity.VO.res.PayUserCaPaperReceiveRes;
import com.youlu.campus.entity.WechatH5UserPO;
import com.youlu.campus.service.activity.impl.ActivityPayConfigService;
import com.youlu.campus.service.activity.impl.PlatformOtherActivityService;
import com.youlu.campus.service.ca.CaTemplateService;
import com.youlu.campus.service.ca.UserCaReceiveHistoryService;
import com.youlu.campus.service.ca.UserPaperCaReceiveHistoryService;
import com.youlu.campus.service.cache.CacheActivityService;
import com.youlu.campus.service.cache.CacheCaCertificateService;
import com.youlu.campus.service.cache.CacheCaGroupInfoService;
import com.youlu.campus.service.cache.CacheCaInfoService;
import com.youlu.campus.service.pay.UserPurchaseCaService;
import com.youlu.campus.service.university.UniversityInfoService;
import com.youlu.campus.service.visitor.UserInfoExtendService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 证书收集
 */
@Slf4j
@Service
public class CaCollectService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private PlatformOtherActivityService platformOtherActivityService;

    @Autowired
    private CaCertificateConfigService caCertificateConfigService;

    @Autowired
    private CaTemplateService caTemplateService;

    @Autowired
    private UniversityInfoService universityInfoService;

    @Autowired
    private CacheActivityService cacheActivityService;
    @Autowired
    private CacheCaCertificateService cacheCaCertificateService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private CertificateActivityConfigService certificateActivityConfigService;


    @Autowired
    private CacheCaGroupInfoService cacheCaGroupInfoService;

    @Autowired
    private CacheCaInfoService cacheCaInfoService;

    @Autowired
    private UserCaReceiveHistoryService userCaReceiveHistoryService;

    @Autowired
    private UserInfoExtendService userInfoExtendService;

    @Resource(name = "masterMongoTemplate")
    private MongoTemplate masterMongoTemplate;

    @Autowired
    private UserPaperCaReceiveHistoryService userPaperCaReceiveHistoryService;
    @Lazy
    @Autowired
    private UserPurchaseCaService userPurchaseCaService;


    private final String CA_CERTIFICATE_LOCK = "ca:certificate:lock:%s:%s:%s:%s";
    private final String CA_CERTIFICATE_V2_LOCK = "ca:certificate:lock:%s:%s:%s:%s:%s";
    private final String CA_CERTIFICATE_NUMBER = "ca:certificate:number:%s:%s:%s:%s";

    @Autowired
    private ActivityPayConfigService activityPayConfigService;

    public PayUserCaPaperReceiveRes getUserCaPaperReceiveByActivityId(UserPO currentUser, String activityId) {
        String openId = currentUser.getOpenId();
        Query query = new Query();
        query.addCriteria(Criteria.where("openId").is(openId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        List<ActivityUserRecord> list = this.mongoTemplate.find(query, ActivityUserRecord.class);
        if (CollectionUtils.isEmpty(list)) {
            log.error(":>>> 用户的待领取证书为空activityId:{},userId:{},openId:{}",
                    activityId, currentUser.getId(), currentUser.getOpenId());
            return null;
        }
        PayConfigPage pageConfig = activityPayConfigService.findByActivityId(activityId, 0);
        if (Objects.isNull(pageConfig)) {
            log.error(":>>> 活动收款配置不存在,activityId:{},type=0", activityId);
            return null;
        }
        Date now = new Date();
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        if (Objects.isNull(activityInfo)) {
            return null;
        }

        PayUserCaPaperReceiveRes payUserCaPaper = new PayUserCaPaperReceiveRes();
        UserInfoExtend userInfoExtend = userInfoExtendService.findCacheUserByUserId(currentUser);
        if (Objects.isNull(userInfoExtend)) {
            payUserCaPaper.setHasAddress(Boolean.FALSE);
        } else {
            if (userInfoExtend.checkUserAdress()) {
                ActivityUserRecord activityUserRecord = list.get(0);
                String recieveName = activityUserRecord.getRecieveName();
                String recieveMobile = activityUserRecord.getRecieveMobile();
                String address = activityUserRecord.getAddress();
                if (!StringUtils.isAllBlank(recieveMobile, recieveName, address)) {
                    payUserCaPaper.setHasAddress(Boolean.TRUE);
                }
            } else {
                payUserCaPaper.setHasAddress(Boolean.FALSE);
            }
        }
        payUserCaPaper.setAvatarUrl(currentUser.getAvatarUrl());
        payUserCaPaper.setBackgroundImgPopupUrl(pageConfig.getBackgroundImgPopupUrl());
        payUserCaPaper.setLevelColor(pageConfig.getLevelColor());
        List<ActivityUserRecord> newList = new ArrayList<>();
        List<PayButtonConfigPage> payButtonConfigList = new ArrayList<>();
//        log.info(":>>> payButtonConfigList:{}", JSON.toJSON(payButtonConfigList));
        List<PayButtonConfigPage> buttonConfigList = pageConfig.getPayButtonConfigList();
        if (CollectionUtils.isNotEmpty(buttonConfigList)) {
            list.stream().forEach(activityUserRecord -> {
                if (StringUtils.isNotBlank(activityUserRecord.getTaskBizType())) {
                    Optional<PayButtonConfigPage> first =
                            buttonConfigList.stream().filter(payButtonConfigPage -> Objects.nonNull(payButtonConfigPage.getEndTime()) && now.before(payButtonConfigPage.getEndTime()) && activityUserRecord.getTaskBizType().equals(payButtonConfigPage.getCaType())).findFirst();
                    if (first.isPresent()) {
                        payButtonConfigList.add(first.get());
                    }
                }
            });
        }
        if (CollectionUtils.isEmpty(payButtonConfigList)) {
            return null;
        }
        List<String> caTypeList = payButtonConfigList.stream().filter(payButtonConfigPage -> PayButtonConfigPage.PAPER_CERTIFICATE.equals(payButtonConfigPage.getButtonType()) && payButtonConfigPage.getPopupPriority() > 0).map(PayButtonConfigPage::getCaType).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(caTypeList)) {
            return null;
        }
        Query query1 = new Query();
        query1.addCriteria(Criteria.where("accountInfoId").is(currentUser.getId()));
        query1.addCriteria(Criteria.where("activityId").is(activityId));
        query1.addCriteria(Criteria.where("taskBizType").in(caTypeList));
        query1.addCriteria(Criteria.where("status").nin("0", "6"));
        List<OrderInfo> orderList = this.mongoTemplate.find(query1, OrderInfo.class);
        Set<String> orderCaTypeSet = new HashSet<>();
        PayButtonConfigPage payButtonConfigPageMax = null;
        if (CollectionUtils.isNotEmpty(orderList)) {
            Set<String> collect = orderList.stream().map(OrderInfo::getTaskBizType).collect(Collectors.toSet());
            orderCaTypeSet.addAll(collect);
            Optional<PayButtonConfigPage> optional = payButtonConfigList.stream().filter(payButtonConfigPage -> !orderCaTypeSet.contains(payButtonConfigPage.getCaType()) && PayButtonConfigPage.PAPER_CERTIFICATE.equals(payButtonConfigPage.getButtonType())).max(Comparator.comparing(PayButtonConfigPage::getPopupPriority));
            if (optional.isPresent()) {
                payButtonConfigPageMax = optional.get();
            }
        } else {
            Optional<PayButtonConfigPage> optional = payButtonConfigList.stream().filter(payButtonConfigPage -> PayButtonConfigPage.PAPER_CERTIFICATE.equals(payButtonConfigPage.getButtonType())).max(Comparator.comparing(PayButtonConfigPage::getPopupPriority));
            if (optional.isPresent()) {
                payButtonConfigPageMax = optional.get();
            }
        }
        if (Objects.nonNull(payButtonConfigPageMax)) {
            payUserCaPaper.setTaskBizType(payButtonConfigPageMax.getCaType());
            payUserCaPaper.setUserInfoCertificateShow(payButtonConfigPageMax.getUserInfoCertificateShow());
            //去除礼品类型等级
            PayButtonConfigPage payButtonConfigPageGift = payButtonConfigList.stream().filter(payButtonConfigPage -> PayButtonConfigPage.PAPER_CERTIFICATE.equals(payButtonConfigPage.getButtonType()) && payButtonConfigPage.getPopupPriority() == 0).findFirst().orElse(null);
            if (Objects.nonNull(payButtonConfigPageGift)) {
                pageConfig.getPayButtonConfigList().stream().filter(payButtonConfigPage -> PayButtonConfigPage.PAPER_CERTIFICATE.equals(payButtonConfigPage.getButtonType())).forEach(payButtonConfigPage -> {
                    List<ActivityUserRecord> recordList = list.stream().filter(activityUserRecord -> !activityUserRecord.getTaskBizType().equals(payButtonConfigPageGift.getCaType())).collect(Collectors.toList());
                    recordList.forEach(activityUserRecord -> {
                        if (payButtonConfigPage.getCaType().equals(activityUserRecord.getTaskBizType())) {
                            if (!orderCaTypeSet.contains(activityUserRecord.getTaskBizType())) {
                                activityUserRecord.setPopupPriority(payButtonConfigPage.getPopupPriority());
                                newList.add(activityUserRecord);
                            }
                        }
                    });
                });
                if (CollectionUtils.isEmpty(newList)) {
                    return null;
                }
                String level = newList.stream().sorted(Comparator.comparing(ActivityUserRecord::getPopupPriority).reversed()).map(ActivityUserRecord::getCaLevel).collect(Collectors.joining(","));
                payUserCaPaper.setLevel(level);
            } else {
                payButtonConfigList.stream().filter(payButtonConfigPage -> PayButtonConfigPage.PAPER_CERTIFICATE.equals(payButtonConfigPage.getButtonType())).forEach(payButtonConfigPage -> {
                    list.forEach(activityUserRecord -> {
                        if (payButtonConfigPage.getCaType().equals(activityUserRecord.getTaskBizType())) {
                            if (!orderCaTypeSet.contains(activityUserRecord.getTaskBizType())) {
                                activityUserRecord.setPopupPriority(payButtonConfigPage.getPopupPriority());
                                newList.add(activityUserRecord);
                            }
                        }
                    });
                });
                if (CollectionUtils.isEmpty(newList)) {
                    return null;
                }
                String level = newList.stream().sorted(Comparator.comparing(ActivityUserRecord::getPopupPriority).reversed()).map(ActivityUserRecord::getCaLevel).collect(Collectors.joining(","));
                payUserCaPaper.setLevel(level);
            }
        }
        newList.clear();
        payButtonConfigList.clear();
        orderCaTypeSet.clear();
        orderList.clear();
        ActivityUserRecord activityUserRecord = list.get(0);
        if (Objects.nonNull(activityUserRecord)) {
            payUserCaPaper.setName(activityUserRecord.getName());
        }
        query = new Query();
        query.addCriteria(Criteria.where("accountInfoId").is(currentUser.getId()));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("status").nin("0", "6"));
        boolean exists = this.mongoTemplate.exists(query, OrderInfo.class);
        if (exists) {
            payUserCaPaper.setPlaceOrder(Boolean.TRUE);
        }
        return payUserCaPaper;
    }

    public PayUserCaPaperReceiveRes getUserCaPaperReceiveByActivityIdV2(UserPO currentUser, String activityId) {
        String openId = currentUser.getOpenId();
        Query query = new Query();
        query.addCriteria(Criteria.where("openId").is(openId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        List<ActivityUserRecord> list = this.mongoTemplate.find(query, ActivityUserRecord.class);
        if (CollectionUtils.isEmpty(list)) {
            log.error(":>>> 用户的待领取证书为空activityId:{},userId:{},openId:{}",
                    activityId, currentUser.getId(), currentUser.getOpenId());
            return null;
        }
        PayConfigPage pageConfig = activityPayConfigService.findByActivityId(activityId, 0);
        if (Objects.isNull(pageConfig)) {
            log.error(":>>> 活动收款配置不存在,activityId:{},type=0", activityId);
            return null;
        }
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        if (Objects.isNull(activityInfo)) {
            return null;
        }
        PayUserCaPaperReceiveRes payUserCaPaper = new PayUserCaPaperReceiveRes();
        UserInfoExtend userInfoExtend = userInfoExtendService.findCacheUserByUserId(currentUser);
        if (Objects.isNull(userInfoExtend)) {
            payUserCaPaper.setHasAddress(Boolean.FALSE);
        } else {
            if (userInfoExtend.checkUserAdress()) {
                ActivityUserRecord activityUserRecord = list.get(0);
                String recieveName = activityUserRecord.getRecieveName();
                String recieveMobile = activityUserRecord.getRecieveMobile();
                String address = activityUserRecord.getAddress();
                if (!StringUtils.isAllBlank(recieveMobile, recieveName, address)) {
                    payUserCaPaper.setHasAddress(Boolean.TRUE);
                }
            } else {
                payUserCaPaper.setHasAddress(Boolean.FALSE);
            }
        }
        payUserCaPaper.setAvatarUrl(currentUser.getAvatarUrl());
        payUserCaPaper.setBackgroundImgPopupUrl(pageConfig.getBackgroundImgPopupUrl());
        payUserCaPaper.setLevelColor(pageConfig.getLevelColor());
        ActivityUserRecord activityUserRecord = list.get(0);
        if (Objects.nonNull(activityUserRecord)) {
            payUserCaPaper.setName(activityUserRecord.getName());
        }
        String level = "";
        for (ActivityUserRecord ar : list) {
            if (StringUtils.isBlank(level)) {
                level = ar.getCaLevel();
            } else {
                if (!level.contains(ar.getCaLevel())) {
                    level = level + "," + ar.getCaLevel();
                }
            }
        }
        payUserCaPaper.setLevel(level);
        query = new Query();
        query.addCriteria(Criteria.where("accountInfoId").is(currentUser.getId()));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("status").nin("0", "6"));
        boolean exists = this.mongoTemplate.exists(query, OrderInfo.class);
        if (exists) {
            payUserCaPaper.setPlaceOrder(Boolean.TRUE);
        }
        // 设置首页弹窗图
        payUserCaPaper.setBackgroundImgPopupUrl(pageConfig.getBackgroundImgPopupUrl());
        payUserCaPaper.setUserInfoCertificateShow(true);
        payUserCaPaper.setStartTime(pageConfig.getStartTime());
        payUserCaPaper.setEndTime(pageConfig.getEndTime());
        List<String> groupIds = userPurchaseCaService.getUserCaGroupId(activityId, currentUser.getId(), currentUser.getMobile(), currentUser.getOpenId());
        List<PayCategoryConfig> cates = userPurchaseCaService.getDefaultCategory(activityId, currentUser.getId(), groupIds);
        if (CollectionUtils.isNotEmpty(cates)) {
            payUserCaPaper.setCategoryId(cates.get(0).getId());
        }
        return payUserCaPaper;
    }

    /**
     * 模拟领取
     *
     * @param activityId
     */
    public void simulateCollect(String activityId) {
        log.info("模拟领取活动->{} 电子证书", activityId);
        Integer pageNo = 1;
        Integer pageSize = 10000;
        while (true) {
            PlatformActivityQueryVO platformActivityQuery = new PlatformActivityQueryVO();
            platformActivityQuery.setActivityId(activityId);
            platformActivityQuery.setPageNo(pageNo);
            platformActivityQuery.setPageSize(pageSize);
            Page<ActivityUserRecord> listPage = platformOtherActivityService.list(platformActivityQuery);
            if (CollectionUtils.isEmpty(listPage.getContent())) {
                break;
            }
            listPage.stream().forEach(user -> {
                String openId = user.getOpenId();
                Query query = new Query();
                query.addCriteria(Criteria.where("openId").is(openId));
                WechatH5UserPO wechatUser = mongoTemplate.findOne(query, WechatH5UserPO.class);
                if (Objects.isNull(wechatUser)) {
                    log.error("订单号 ->{} 信息中openid 不存在", openId);
                    return;
                }
                UserPO currentUser = new UserPO();
                BeanUtils.copyProperties(user, currentUser);
                currentUser.setId(wechatUser.getAccountInfoId());
                currentUser.setOpenId(openId);
                CaCollectReq caCollectReq = new CaCollectReq();
                caCollectReq.setCurrentUser(currentUser);
                caCollectReq.setActivityId(activityId);
                caCollectReq.setCaType("1");
                this.collect(caCollectReq);
            });
            pageNo++;

        }


    }


    public Map<String, Object> checkUser(CaCollectReq caCollectReq) {
        String activityId = caCollectReq.getActivityId();
        String taskBizType = caCollectReq.getTaskBizType();
        UserPO currentUser = caCollectReq.getCurrentUser();
        String openId = currentUser.getOpenId();
        String mobile = caCollectReq.getMobile();
        Map<String, Object> result = new HashMap<>(1);
        result.put("hasAddress", Boolean.TRUE);
        log.info(" 校验用户  - > {} 是否参与了活动 - > {} 领取证书类型 - > {}", openId, activityId, taskBizType);
        ActivityUserRecord activityUserRecord = platformOtherActivityService.checkUser(activityId, openId, mobile, taskBizType);
        //电子证书
        if ("1".equals(caCollectReq.getCaType())) {
            this.checkGongXianZhi(activityUserRecord);
            result.put("hasAddress", Boolean.TRUE);
            return result;
        }
        //纸质证书
        if ("2".equals(caCollectReq.getCaType())) {
            UserInfoExtend userInfoExtend = userInfoExtendService.findCacheUserByUserId(currentUser);
            if (Objects.isNull(userInfoExtend)) {
                result.put("hasAddress", Boolean.FALSE);
                return result;
            }
            if (userInfoExtend.checkUserAdress()) {
                String recieveName = activityUserRecord.getRecieveName();
                String recieveMobile = activityUserRecord.getRecieveMobile();
                String address = activityUserRecord.getAddress();
                if (!StringUtils.isAllBlank(recieveMobile, recieveName, address)) {
                    result.put("hasAddress", Boolean.TRUE);
                }
            } else {
                result.put("hasAddress", Boolean.FALSE);
            }

            return result;
        }
        return result;

    }

    public Map<String, Object> checkUserV2(CaCollectReq caCollectReq) {
        log.info(":>>> checkUserV2:{}", JSON.toJSON(caCollectReq));
        if (StringUtils.isBlank(caCollectReq.getCategoryId())) {
            log.error(":>>> 分类为空:");
            throw new BusinessException("参数错误!");
        }
        Query queryCate = new Query();
        queryCate.addCriteria(Criteria.where("id").is(caCollectReq.getCategoryId()));
        PayCategoryConfig categoryConfig = mongoTemplate.findOne(queryCate, PayCategoryConfig.class);
        if (Objects.isNull(categoryConfig)) {
            log.error(":>>> 分类配置不存在:{}", caCollectReq.getCategoryId());
            throw new BusinessException("请联系客服处理！");
        }
        CaGroupInfo groupInfo = cacheCaGroupInfoService.findById(categoryConfig.getCaGroupId());
        String taskBizType = groupInfo.getTaskBizType();
        String activityId = caCollectReq.getActivityId();
        UserPO currentUser = caCollectReq.getCurrentUser();
        String openId = currentUser.getOpenId();
        String mobile = caCollectReq.getMobile();
        Map<String, Object> result = new HashMap<>(1);
        result.put("hasAddress", Boolean.TRUE);
        log.info(" 校验用户  - > {} 是否参与了活动 - > {} 领取证书类型 - > {}", openId, activityId, taskBizType);
        ActivityUserRecord activityUserRecord = platformOtherActivityService.checkUser(activityId, openId, mobile,
                taskBizType);
        if (StringUtils.isNotBlank(caCollectReq.getCaType()) && caCollectReq.getCaType().equals("1")) {
            this.checkGongXianZhi(activityUserRecord);
            result.put("hasAddress", Boolean.TRUE);
            return result;
        }
        //纸质证书
        if ("2".equals(caCollectReq.getCaType())) {
            UserInfoExtend userInfoExtend = userInfoExtendService.findCacheUserByUserId(currentUser);
            if (Objects.isNull(userInfoExtend)) {
                result.put("hasAddress", Boolean.FALSE);
                return result;
            }
            if (userInfoExtend.checkUserAdress()) {
                String recieveName = activityUserRecord.getRecieveName();
                String recieveMobile = activityUserRecord.getRecieveMobile();
                String address = activityUserRecord.getAddress();
                if (!StringUtils.isAllBlank(recieveMobile, recieveName, address)) {
                    result.put("hasAddress", Boolean.TRUE);
                }
            } else {
                result.put("hasAddress", Boolean.FALSE);
            }

            return result;
        }
        return result;

    }


    public synchronized CaCollectRes collect(CaCollectReq caCollectReq) {
        String activityId = caCollectReq.getActivityId();
        String taskBizType = caCollectReq.getTaskBizType();
        UserPO currentUser = caCollectReq.getCurrentUser();
        String openId = currentUser.getOpenId();
        String mobile = caCollectReq.getMobile();
        log.info("当前用户  - > {} 参与了活动 - > {} 正在领取证书 - > {}", openId, activityId, taskBizType);
        ActivityUserRecord activityUser = new ActivityUserRecord();
        //wechat-mini 平台单独处理
        if (StringUtils.isNotBlank(caCollectReq.getPlatform()) && "wechat-mini".equals(caCollectReq.getPlatform())) {
            activityUser.setActivityId(caCollectReq.getActivityId());
            activityUser.setCaLevel(caCollectReq.getCaLevel());
            activityUser.setName(caCollectReq.getName());
            activityUser.setUniversityId(caCollectReq.getUniversityId());
            activityUser.setUniversityName(caCollectReq.getUniversityName());
            activityUser.setMobile(mobile);
        } else {
            try {
                activityUser = platformOtherActivityService.findByOpenidOrMoble(activityId, openId, mobile, taskBizType);
            } catch (Exception e) {
                log.error(":>>> 同步电子证书错误:{}", e);
                activityUser.setActivityId(caCollectReq.getActivityId());
                activityUser.setCaLevel(caCollectReq.getCaLevel());
                activityUser.setName(caCollectReq.getName());
                activityUser.setUniversityId(caCollectReq.getUniversityId());
                activityUser.setUniversityName(caCollectReq.getUniversityName());
                activityUser.setMobile(mobile);
            }

        }

        if (StringUtils.isNotBlank(caCollectReq.getCaType()) && caCollectReq.getCaType().equals("1")) {
            checkGongXianZhi(activityUser);
            activityUser.setDigitalCa(Boolean.TRUE);
        } else {
            //纸质
            activityUser.setDigitalCa(Boolean.FALSE);
        }
        String caLevel = activityUser.getCaLevel();
        if (Objects.isNull(caLevel) || StringUtils.isBlank(caLevel)) {
            log.error(":>>> 严重警告---|||||||||111111");
            caLevel = caCollectReq.getCaLevel();
            log.error(":>>> 严重警告---|||||||||2222,证书等级为空:使用订单中的等级:{}", caCollectReq.getCaLevel());
        }
        CertificateActivityConfig certificateActivityConfig =
                certificateActivityConfigService.findByActivityIdAndBizType(activityId, taskBizType);
        CaCertificateConfig caCertificateConfig =
                caCertificateConfigService.findByActivityIdAndCaTypeAndCaLevel(activityId, taskBizType, caLevel);
        CaTemplate caTemplate = caTemplateService.detail(caCertificateConfig.getTemplateId());
        caCollectReq.setCaLevel(caLevel);
        activityUser.setCaTime(certificateActivityConfig.getCaTime());
        String letterStart = certificateActivityConfig.getLetterStart();
        String lockKey = "";
        if ("v1".equals(caCollectReq.getVersion())) {
            lockKey = String.format(CA_CERTIFICATE_LOCK, activityId, currentUser.getId(), taskBizType,
                    activityUser.getCaLevel());
        } else if ("v2".equals(caCollectReq.getVersion())) {
            lockKey = String.format(CA_CERTIFICATE_V2_LOCK, activityId, currentUser.getId(), taskBizType,
                    activityUser.getCaLevel(), caCollectReq.getSubOrderNo());
        }
        log.info("【证书编号】获取锁信息->{}", lockKey);
        Boolean existKey = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 2L, TimeUnit.SECONDS);
        log.info("【证书编号】获取锁状态->{}", existKey);
        if (Objects.nonNull(existKey) && !existKey) {
            log.error(":>>> 生成证书编号获取锁错误2:{}", lockKey);
            try {
                log.error(":>>> 开始获取锁失败，等待5秒再执行...:::");
                Thread.sleep(5000);
                log.error(":>>> 结束获取锁失败，等待5秒再执行...:::");
                existKey = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 2L, TimeUnit.SECONDS);
            } catch (Exception e) {
                log.error(":>>> 获取锁失败，等待5秒再执行...:{}", e);
            }
            if (Objects.nonNull(existKey) && !existKey) {
                log.error(":>>> 生成证书编号获取锁错误:{}", lockKey);
                throw new BusinessException("对不起哦，服务繁忙,稍后重试2");
            }
        }
        //caCollectReq.set
        String certificateNo = buildCertificateNo(caCollectReq, letterStart, mobile);
        CaCollectRes caCollect = new CaCollectRes();
        caTemplate.setCaName(caCertificateConfig.getCertificateName());
        caCollect.setCaTemplate(caTemplate);
        caCollect.setCertificateNo(certificateNo);
        String universityName = activityUser.getUniversityName();
        if (StringUtils.isBlank(universityName)) {
            UniversityInfo universityInfo = universityInfoService.findOne(activityUser.getUniversityId());
            if (Objects.nonNull(universityInfo)) {
                universityName = universityInfo.getName();
                activityUser.setUniversityName(universityName);
            }
        } else {
            universityName = activityUser.getUniversityName();
        }
        caCollect.setUniversityName(universityName);
        caCollect.setUserName(activityUser.getName());
        if (caCollectReq.getNowCaBuild()) {
            caBuild(certificateNo, activityUser, caTemplate);
        }
        if (StringUtils.isBlank(activityUser.getCaTime())) {
            caCollect.setCaTime(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        } else {
            caCollect.setCaTime(activityUser.getCaTime());
        }
        log.info("用户->{}生成电子证书编号->{}", currentUser.getId(), certificateNo);
        //新增电子证书领取历史记录
        if ("wechat-mini".equals(currentUser.getCurrentPlatform()) && caCollectReq.getCaType().equals("2")) {
            UserPaperCaReceiveHistory userCaReceiveHistory = new UserPaperCaReceiveHistory();
            userCaReceiveHistory.setUserId(currentUser.getId());
            userCaReceiveHistory.setActivityId(activityId);
            userCaReceiveHistory.setActivityName(certificateActivityConfig.getActivityName());
            userCaReceiveHistory.setCaLevel(caLevel);
            userCaReceiveHistory.setCaTemplateImgUrl(caTemplate.getBackgroundPic().getUrl());
            userCaReceiveHistory.setCaType(taskBizType);
            userCaReceiveHistory.setCaTemplateId(caTemplate.getId());
            userCaReceiveHistory.setReceiveTime(caCollect.getCaTime());
            userCaReceiveHistory.setAppId(currentUser.getAppId());
            userCaReceiveHistory.setPlatform(currentUser.getCurrentPlatform());
            userPaperCaReceiveHistoryService.saveOrUpdate(userCaReceiveHistory);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("certificateNo").is(certificateNo));
        UserCaRecord userCaRecord = this.masterMongoTemplate.findOne(query, UserCaRecord.class);
        if (Objects.nonNull(userCaRecord)) {
            caCollect.setCaTime(userCaRecord.getCaTime());
        }
        Date pubDate = DateUtil.parseDate(caCollect.getCaTime());
        String caTimeStr = DateUtil.format(pubDate, "yyyy年M月d日");
        caCollect.setCaTime(caTimeStr);
        return caCollect;
    }

    //是否需要校验贡献值
    private void checkGongXianZhi(ActivityUserRecord activityUserRecord) {
        String activityId = activityUserRecord.getActivityId();
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
//        ActivityInfo activityInfo = activityService.findOne(activityUserRecord.getActivityId());
        Integer receiveCaValue = activityInfo.getReceiveCaValue();
        if (activityInfo.getReceiveCaValue() == 0) {
            return;
        }
        Integer q = activityUserRecord.getQ();
        log.info("领取电子证书-实时】 当前用户->{} 参与活动->{} 贡献值-> {} 规则贡献值->{}", activityUserRecord.getMobile(),
                activityId, q, receiveCaValue);
        if (q < receiveCaValue) {
            throw new BusinessException(activityInfo.getReceiveCaErrorTips());
        }
    }

    @Async
    public void caBuild(String certificateNo,
                        ActivityUserRecord activityUserRecord, CaTemplate caTemplateActivity) {
        Query query = new Query();
        query.addCriteria(Criteria.where("certificateNo").is(certificateNo));
        UserCaRecord userCaRecord = this.mongoTemplate.findOne(query, UserCaRecord.class);
        if (Objects.nonNull(userCaRecord)) {
            return;
        }
        userCaRecord = new UserCaRecord();
        userCaRecord.setCertificateNo(certificateNo);
        userCaRecord.setUserName(activityUserRecord.getName());
        userCaRecord.setMobile(activityUserRecord.getMobile());
        userCaRecord.setUniversityName(activityUserRecord.getUniversityName());
        userCaRecord.setCaName(caTemplateActivity.getCaName());
        userCaRecord.setLevelName(activityUserRecord.getCaLevel());
        userCaRecord.setDigitalCa(activityUserRecord.getDigitalCa());
        if (StringUtils.isNotBlank(activityUserRecord.getCaTime())) {
            userCaRecord.setCaTime(activityUserRecord.getCaTime());
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            userCaRecord.setCaTime(sdf.format(new Date()));
        }

        ActivityInfo activityInfo = cacheActivityService.findById(activityUserRecord.getActivityId());
        if (Objects.nonNull(activityInfo)) {
            Set<ActivityCaOrg> activityCaOrgSet = activityInfo.getActivityCaOrgSet();
            if (CollectionUtils.isNotEmpty(activityCaOrgSet)) {
                AtomicInteger index = new AtomicInteger(0);
                UserCaOrg[] caOrgArray = new UserCaOrg[activityCaOrgSet.size()];
                activityCaOrgSet.stream().forEach(caOrg -> {
                    UserCaOrg userCaOrg = new UserCaOrg();
                    userCaOrg.setCaOrganizationId(caOrg.getCaOrganizationId());
                    userCaOrg.setCaOrganizationName(caOrg.getCaOrganizationName());
                    userCaOrg.setStampImage(caOrg.getStampImage());
                    caOrgArray[index.get()] = userCaOrg;
                    index.incrementAndGet();
                });
                userCaRecord.setCaOrg(caOrgArray);
            }
        }
        userCaRecord.setActivityId(activityInfo.getId());
        userCaRecord.setActivityName(activityInfo.getName());
        this.mongoTemplate.save(userCaRecord);
    }


    public UserParticipateActivityInfo getUserParticipateActivity(String userId, String activityId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("joined").is(Boolean.TRUE));
        UserParticipateActivityInfo userParticipateActivityInfo = this.mongoTemplate.findOne(query,
                UserParticipateActivityInfo.class);
        if (Objects.isNull(userParticipateActivityInfo)) {
            throw new BusinessException("对不起,你未参与活动，不能领取证书");
        }
        return userParticipateActivityInfo;
    }

    /**
     * 生成证书编号-后期优化
     *
     * @param letterStart
     * @return
     */
    public String buildCertificateNo(CaCollectReq caCollectReq, String letterStart) {
        String activityId = caCollectReq.getActivityId();
        String caLevel = caCollectReq.getCaLevel();
        UserPO currentUser = caCollectReq.getCurrentUser();

        CaCertificateLog caCertificateLog = cacheCaCertificateService.getCaCertificate(activityId, currentUser.getId()
                , caCollectReq.getTaskBizType(), caLevel);
        if (Objects.nonNull(caCertificateLog)) {
            return caCertificateLog.getCertificateNo();
        }
        String certificateNo = generateCertificateNumber(caCollectReq, letterStart);
        caCertificateLog = new CaCertificateLog();
        caCertificateLog.setCertificateNo(certificateNo);
        caCertificateLog.setActivityId(activityId);
        caCertificateLog.setCaLevel(caLevel);
        caCertificateLog.setCaType(caCollectReq.getTaskBizType());
        caCertificateLog.setUserId(currentUser.getId());
        this.mongoTemplate.save(caCertificateLog);
        return certificateNo;
    }

    /**
     * 生成证书编号-后期优化
     *
     * @param letterStart
     * @return
     */
    public String buildCertificateNo(CaCollectReq caCollectReq, String letterStart, String mobile) {
        String activityId = caCollectReq.getActivityId();
        String caLevel = caCollectReq.getCaLevel();
        UserPO currentUser = caCollectReq.getCurrentUser();

        CaCertificateLog caCertificateLog = cacheCaCertificateService.getCaCertificate(
                activityId,
                currentUser.getId(),
                caCollectReq.getTaskBizType(),
                caLevel,
                mobile);
        if (Objects.nonNull(caCertificateLog)) {
            return caCertificateLog.getCertificateNo();
        }
        String certificateNo = generateCertificateNumber(caCollectReq, letterStart);
        caCertificateLog = new CaCertificateLog();
        caCertificateLog.setCertificateNo(certificateNo);
        caCertificateLog.setActivityId(activityId);
        caCertificateLog.setCaLevel(caLevel);
        caCertificateLog.setCaType(caCollectReq.getTaskBizType());
        caCertificateLog.setUserId(currentUser.getId());
        caCertificateLog.setMobile(mobile);
        this.mongoTemplate.save(caCertificateLog);
        return certificateNo;
    }

    private String generateCertificateNumber(CaCollectReq caCollectReq, String letterStart) {
        String caType = caCollectReq.getCaType();
        String activityId = caCollectReq.getActivityId();
        String caLevel = caCollectReq.getCaLevel();
        //是否是电子证书

        String caGroupNumber = "";
        String caEditionNumber = "";
        if (caType.equals("1")) {
            caGroupNumber = "9";
            caEditionNumber = "99";
        } else {
            Map<String, String> mapCertificateType = cacheCaGroupInfoService.findByActivityId(activityId);
            caGroupNumber = mapCertificateType.get(activityId + "-" + caCollectReq.getTaskBizType());
            String caGroupId = caCollectReq.getCaGroupId();
            String edition = caCollectReq.getEdition();
            Map<String, String> mapCaInfo = cacheCaInfoService.findByActivityIdAndGroupId(activityId, caGroupId);
            caEditionNumber = mapCaInfo.get(caGroupId + "-" + edition + "-" + caLevel);
        }
        String certificateNo = "";
        String yyMMdd = DateFormatUtils.format(new Date(), "yyMMdd");
        String certKey = String.format(CA_CERTIFICATE_NUMBER, activityId, letterStart + yyMMdd, caGroupNumber,
                caEditionNumber);
        String existCert = this.redisTemplate.opsForValue().get(certKey);
        if (StringUtils.isBlank(existCert)) {
            Long initCertificateNumber = initCertificateNumber(caType);
            this.redisTemplate.opsForValue().set(certKey, initCertificateNumber.toString(), 24L, TimeUnit.HOURS);
            if (caType.equals("1")) {
                certificateNo = letterStart + yyMMdd + initCertificateNumber.toString();
            } else {
                certificateNo =
                        letterStart + yyMMdd + caGroupNumber + caEditionNumber + initCertificateNumber.toString();
            }
        } else {
            Long incrNo = this.redisTemplate.opsForValue().increment(certKey, 1);
            if (caType.equals("1")) {
                certificateNo = letterStart + yyMMdd + caGroupNumber + incrNo;
            } else {
                certificateNo = letterStart + yyMMdd + caGroupNumber + caEditionNumber + incrNo;
            }
        }
        Boolean exist = cacheCaCertificateService.existsByCertificateNo(certificateNo);
        if (exist) {
            log.error("【领取证书编号重复】重新生成 ->{}", certificateNo);
            return generateCertificateNumber(caCollectReq, letterStart);
        }
        return certificateNo;
    }

    public static void main(String[] args) {
        String MMdd = DateFormatUtils.format(new Date(), "MMddHH");
        System.out.println(MMdd);
    }

    private Long initCertificateNumber(String caType) {
//        Date current = new Date();
//        String mmDD = DateFormatUtils.format(current, "MMddHH");
        if (caType.equals("1")) {
            return Long.valueOf("1000001");
        }
        return Long.valueOf("10001");
    }

    public String test(String activityId, String letterStart) {
        String certificateNo = "";
//        String yyMMdd = DateFormatUtils.format(new Date(), "yyMMdd");
//        String certKey = String.format(CA_CERTIFICATE_NUMBER, activityId,letterStart+yyMMdd);
//        String existCert = this.redisTemplate.opsForValue().get(certKey);
//        if(StringUtils.isBlank(existCert)){
//            Long initCertificateNumber = initCertificateNumber();
//            this.redisTemplate.opsForValue().set(certKey,initCertificateNumber.toString(),24L,TimeUnit.HOURS);
//            certificateNo = letterStart + yyMMdd+initCertificateNumber.toString();
//        }else{
//            Long incrNo = this.redisTemplate.opsForValue().increment(certKey, 1);
//            certificateNo =  letterStart + yyMMdd+ incrNo;
//        }
        log.info("证书编号" + certificateNo);
        return certificateNo;
    }

    public void build(String activityId, String openid, String caType, String caLevel) {
        // ActivityUserRecord one = this.mongoTemplate.findOne(query, ActivityUserRecord.class);
        CaCertificateConfig caCertificateConfig =
                caCertificateConfigService.findByActivityIdAndCaTypeAndCaLevel(activityId, caType, caLevel);
        CaTemplate caTemplate = caTemplateService.detail(caCertificateConfig.getTemplateId());
        CaBackgroundPic backgroundPic = caTemplate.getBackgroundPic();
        CertificateNoInfo certificateNo = caTemplate.getCertificateNo();
        CaTemplateUniversity university = caTemplate.getUniversity();
        try {
            BufferedImage background = resizeImage(Integer.valueOf(backgroundPic.getWidth()),
                    Integer.valueOf(backgroundPic.getHeight()),
                    ImageIO.read(new URL(backgroundPic.getUrl())));
            Graphics2D graphics2D = background.createGraphics();
            graphics2D.setColor(Color.WHITE);
            Font font = new Font("微软雅黑", Font.BOLD, 12);
            graphics2D.setFont(font);
            //消除锯齿状
            graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                    RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
            String axisX = university.getAxisX();
            String axisY = university.getAxisY();
            log.info("证书 学校文字 坐标 X-> {}, Y ->{}", axisX, axisY);
            // 计算文字长度，计算居中的x点坐标
            FontMetrics fm = graphics2D.getFontMetrics(font);
            int textWidth = fm.stringWidth("学校名称aaaaaaaaaaaaa");
            graphics2D.drawString("学校名称aaaaaaaaaaaaa", Integer.valueOf(axisX), Integer.valueOf(axisY));
            graphics2D.dispose();
            ImageIO.write(background, "png", new File("/data/img/test.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public static BufferedImage resizeImage(Integer x, Integer y, BufferedImage bfi) {
        BufferedImage bufferedImage = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
        bufferedImage.getGraphics().drawImage(bfi.getScaledInstance(x, y, Image.SCALE_SMOOTH), 0, 0, null);
        return bufferedImage;
    }


}